package io.itit.ecp.admin.provide.action.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import icu.mhb.mybatisplus.plugln.extend.Joins;
import io.itit.ecp.admin.provide.action.req.CarbonNeutralityPlanQueryReq;
import io.itit.ecp.admin.provide.action.req.CarbonNeutralityPlanReq;
import io.itit.ecp.admin.provide.action.resp.CarbonNeutralityPlanResp;
import io.itit.ecp.admin.server.entity.CarbonNeutralityPlanDataEntity;
import io.itit.ecp.admin.server.entity.CarbonNeutralityPlanEntity;
import io.itit.ecp.admin.server.entity.SceneProjectEntity;
import io.itit.ecp.admin.server.service.ICarbonNeutralityPlanDataService;
import io.itit.ecp.admin.server.service.ICarbonNeutralityPlanService;
import io.itit.grass.common.provide.action.req.BaseBatchIdReq;
import io.itit.grass.common.provide.action.req.BaseIdReq;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.itit.grass.common.provide.action.validation.IAdd;
import io.itit.grass.common.provide.action.validation.IQueryPage;
import io.itit.grass.common.provide.action.validation.IRequired;
import io.itit.grass.common.provide.action.validation.IUpdate;
import io.itit.grass.common.server.entity.BaseEntity;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.web.wall.utils.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * @Author：Roy
 * @Description：碳中和规划
 * @Date：Create by 2023-11-23 16:28:52
 */
@Api(tags = "碳中和规划")
@RestController
@RequestMapping("/ecp-admin/carbonNeutralityPlan")
public class CarbonNeutralityPlanController {

    @Resource
    private ICarbonNeutralityPlanService carbonNeutralityPlanService;

    @Resource
    private ICarbonNeutralityPlanDataService carbonNeutralityPlanDataService;

    @ApiOperation("分页查询")
    @PostMapping("queryPage")
    @RequiresPermissions("ecp-admin:carbonNeutralityPlan:search")
    public ResultResp<IPage<CarbonNeutralityPlanResp>> queryPage(@RequestBody @Validated(IQueryPage.class) CarbonNeutralityPlanQueryReq req) {
        return ResultResp.success(buildQW(req).joinPage(PageUtils.getPage(req, CarbonNeutralityPlanResp.class), CarbonNeutralityPlanResp.class));
    }

    @ApiOperation("查询在指定时间范围内是否存在有效的数据")
    @PostMapping("queryrangedataexist")
    public ResultResp<Boolean> queryRangeDataExist(@RequestBody CarbonNeutralityPlanReq req) {
        LocalDate start = req.getEffectiveTimeStart();
        LocalDate end = req.getEffectiveTimeEnd();
        List<CarbonNeutralityPlanEntity> list = carbonNeutralityPlanService.list(new LambdaQueryWrapper<CarbonNeutralityPlanEntity>()
                .eq(CarbonNeutralityPlanEntity::getSceneProjectId, req.getSceneProjectId())
                .le(CarbonNeutralityPlanEntity::getEffectiveTimeStart, start)
                .ge(CarbonNeutralityPlanEntity::getEffectiveTimeEnd, start)
        );
        Set<String> ids = list.stream().map(BaseEntity::getId).collect(Collectors.toSet());
        list.addAll(carbonNeutralityPlanService.list(new LambdaQueryWrapper<CarbonNeutralityPlanEntity>()
                .notIn(!ids.isEmpty(), CarbonNeutralityPlanEntity::getId, ids)
                .eq(CarbonNeutralityPlanEntity::getSceneProjectId, req.getSceneProjectId())
                .le(CarbonNeutralityPlanEntity::getEffectiveTimeStart, end)
                .ge(CarbonNeutralityPlanEntity::getEffectiveTimeEnd, end)
        ));
        int size = list.size();
        if (size == 1) {
            return ResultResp.success(!list.get(0).getId().equals(req.getId()));
        }
        return ResultResp.success(size > 1);
    }

    @ApiOperation(("查询在指定时间范围内规划碳中和"))
    @PostMapping("queryplanCarbonNeutrality")
    public ResultResp<BigDecimal> queryPlanCarbonNeutrality(@RequestBody CarbonNeutralityPlanReq req) {
        return ResultResp.success(carbonNeutralityPlanService.queryPlanCarbonNeutrality(req.getSceneProjectId(),
                req.getEffectiveTimeStart(), req.getEffectiveTimeEnd()));
    }

    @ApiOperation("新增")
    @PostMapping("add")
    @RequiresPermissions("ecp-admin:carbonNeutralityPlan:add")
    @Transactional
    public ResultResp<Boolean> add(@RequestBody @Validated({IAdd.class}) CarbonNeutralityPlanReq req) throws Exception {
        CarbonNeutralityPlanEntity planEntity = ConvertUtils.copy(req, CarbonNeutralityPlanEntity.class);
        boolean result = carbonNeutralityPlanService.saveOrUpdate(planEntity);
        List<CarbonNeutralityPlanDataEntity> dataEntities = new ArrayList<>();
        LocalDate item = req.getEffectiveTimeStart();
        LocalDate end = req.getEffectiveTimeEnd();
        while (item.isEqual(end) || item.isBefore(end)) {
            CarbonNeutralityPlanDataEntity entity = new CarbonNeutralityPlanDataEntity();
            entity.setPlanId(planEntity.getId());
            entity.setSceneProjectId(planEntity.getSceneProjectId());
            entity.setSolidifyDate(item);
            entity.setPlanCarbonEmissions(planEntity.getPlanCarbonEmissions());
            entity.setPlanCarbonNeutrality(planEntity.getPlanCarbonNeutrality());
            entity.setPlanCarbonZero(planEntity.getPlanCarbonZero());
            entity.setPlanCarbonSequestration(planEntity.getPlanCarbonSequestration());
            dataEntities.add(entity);
            item = item.plusDays(1);
        }
        carbonNeutralityPlanDataService.saveBatch(dataEntities);
        return ResultResp.success(result);
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    @Transactional
    @RequiresPermissions("ecp-admin:carbonNeutralityPlan:update")
    public ResultResp<Boolean> update(@RequestBody @Validated({IUpdate.class}) CarbonNeutralityPlanReq req) throws Exception {
        carbonNeutralityPlanDataService.remove(new LambdaQueryWrapper<CarbonNeutralityPlanDataEntity>()
                .eq(CarbonNeutralityPlanDataEntity::getPlanId, req.getId()));
        return this.add(req);
    }

    @ApiOperation("删除(根据Id删)")
    @PostMapping("deleteById")
    @RequiresPermissions("ecp-admin:carbonNeutralityPlan:deleteById")
    @Transactional
    public ResultResp<Boolean> deleteById(@RequestBody @Validated({IRequired.class}) BaseIdReq req) {
        carbonNeutralityPlanDataService.remove(new LambdaQueryWrapper<CarbonNeutralityPlanDataEntity>()
                .eq(CarbonNeutralityPlanDataEntity::getPlanId, req.getId()));
        return ResultResp.success(carbonNeutralityPlanService.removeById(req.getId()));
    }

    @ApiOperation("批量删除")
    @PostMapping("batchDelete")
    @RequiresPermissions("ecp-admin:carbonNeutralityPlan:batchDelete")
    @Transactional
    public ResultResp<Boolean> batchDelete(@RequestBody @Validated({IRequired.class}) BaseBatchIdReq req) {
        carbonNeutralityPlanDataService.remove(new LambdaQueryWrapper<CarbonNeutralityPlanDataEntity>()
                .in(CarbonNeutralityPlanDataEntity::getPlanId, req.getIds()));
        carbonNeutralityPlanService.removeBatchByIds(req.getIds(), 500);
        return ResultResp.success();
    }

    private static JoinLambdaWrapper<CarbonNeutralityPlanEntity> buildQW(CarbonNeutralityPlanQueryReq req) {
        return Joins.of(CarbonNeutralityPlanEntity.class)
                .selectAll()
                .leftJoin(SceneProjectEntity.class, SceneProjectEntity::getId, CarbonNeutralityPlanEntity::getSceneProjectId)
                .selectAs(SceneProjectEntity::getProjectName, CarbonNeutralityPlanResp::getProjectName)
                .end()
                .eq(StringUtils.isNotEmpty(req.getSceneProjectId()), CarbonNeutralityPlanEntity::getSceneProjectId, req.getSceneProjectId())
                .ge(Objects.nonNull(req.getEffectiveTimeStart()), CarbonNeutralityPlanEntity::getEffectiveTimeStart, req.getEffectiveTimeStart())
                .le(Objects.nonNull(req.getEffectiveTimeEnd()), CarbonNeutralityPlanEntity::getEffectiveTimeEnd, req.getEffectiveTimeEnd())
                .last(StringUtils.isNotEmpty(req.getSortColumn()), PageUtils.lastOrderBy(req))
                .orderByDesc(CarbonNeutralityPlanEntity::getCreateTm);
    }


}
